package com.ewancle;

import com.alibaba.fastjson2.JSON;
import com.ewancle.model.KnowlCat;
import com.ewancle.model.Subject;
import com.ewancle.model.Topic;
import com.ewancle.model.TopicSubject;
import com.ewancle.utils.PostgreSqlJdbc;
import com.ewancle.utils.SnowflakeIdGenerator;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.io.IOException;
import java.sql.SQLException;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;

public class SeleniumTestTopic {

    public static void main(String[] args) {

        System.out.println("开始时间："+LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        String os = System.getProperty("os.name");
        //Windows操作系统
        if (os != null && os.toLowerCase().startsWith("windows")) {
            System.out.println(String.format("当前系统版本是:%s", os));
            System.setProperty("webdriver.chrome.driver", "src/test/resources/chromedriver.exe");
        } else if (os != null && os.toLowerCase().startsWith("linux")) {//Linux操作系统
            System.out.println(String.format("当前系统版本是:%s", os));
            System.setProperty("webdriver.chrome.driver", "src/test/resources/chromedriver");
        } else { //其它操作系统
            System.out.println(String.format("当前系统版本是:%s", os));
        }

        //String userAgent="Mozilla/7.0 (Linux; Android 13.1.0; Nexus 9X Build/OPM4.171019.026) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.4472.77 Mobile Safari/537.36";
        String userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36";
        ChromeOptions options = new ChromeOptions();
        // 模拟安卓设备，设置设备为 Nexus 5X
        /*Map<String, Object> mobileEmulation = new HashMap<>();
        //mobileEmulation.put("deviceName", "Nexus 9X");
        mobileEmulation.put("width", 1440);  // Nexus 9X 屏幕宽度（假设）
        mobileEmulation.put("height", 2560); // Nexus 9X 屏幕高度（假设）
        mobileEmulation.put("pixelRatio", 3.0);  // Nexus 9X 像素比（假设）
        options.setExperimentalOption("mobileEmulation", mobileEmulation);*/
        // 设置设备屏幕尺寸和视口，模拟手机端
        //options.addArguments("--window-size=1440,2560");  // iPhone 6分辨率

        // 设置其它 Chrome 配置选项
        options.addArguments("--disable-blink-features=AutomationControlled"); // 禁用自动化特性,在某些网站上，Selenium 可能被检测为自动化工具，可以通过禁用 webdriver 特性来绕过检测。
        options.addArguments("--disable-extensions");  // 禁用扩展

        options.addArguments("--disable-gpu");  // 禁用 GPU
        options.addArguments("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7");
        options.addArguments("Accept-Language", "en-US,en;q=0.9");
        //options.addArguments("accept-encoding", "gzip, deflate, br, zstd");
        options.addArguments("Connection", "keep-alive");
        //options.addArguments("Upgrade-Insecure-Requests", "1");
        options.setExperimentalOption("useAutomationExtension", false); // 通过 setExperimentalOption 启用一些实验性的 Chrome 功能

        // 设置 User-Agent 和其他请求头，模拟真实的安卓设备浏览器
        options.addArguments("user-agent="+userAgent);
        WebDriver driver = null;
        try {
            // 创建 WebDriver 实例
            driver = new ChromeDriver(options);
            //修改 WebDriver 属性: 某些网站会通过 navigator.webdriver 判断是否是自动化浏览器。可以通过 JavaScript 设置这些属性来避免被识别为 Selenium
            JavascriptExecutor js = (JavascriptExecutor) driver;
            js.executeScript("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})");

            // 访问网页
            driver.get("https://www.ahuyikao.com/login/passwordlogin.html");
            // 等待页面加载（这里使用 JavaScript 来确保页面完全加载）
            waitForPageLoad(driver);
            // 避免过快的请求频率，模拟正常用户的浏览行为。设置合理的等待时间和点击间隔。
            // 随机等待 3 到 7 秒，模拟正常用户行为
            Thread.sleep(1000 + (long) (Math.random() * 2000));

            // 定位输入框，并输入文本（使用 By 类来选择网页元素，如 By.id(), By.name(), By.xpath() 等。）
            WebElement inputField = driver.findElement(By.id("phones"));
            inputField.sendKeys("13337839087");

            WebElement inputField1 = driver.findElement(By.id("passwords"));
            inputField1.sendKeys("yunsheng6088");

            // 定位按钮并点击
            WebElement button = driver.findElement(By.xpath("//*[@id=\"login_password_form\"]/div[3]/button"));
            button.click();
            Thread.sleep(10000 + (long) (Math.random() * 2000));

            // 查找并点击 Layui 弹窗的关闭按钮 (登录完拖动验证码后，关闭弹窗）
            WebElement closeButton = driver.findElement(By.xpath("//*[@id=\"layui-layer2\"]/div[3]/a"));
            closeButton.click();  // 点击关闭按钮

            // 模拟鼠标移动和点击(登录完拖动验证码后，模拟菜单跳转）
            Actions actions = new Actions(driver);
            WebElement element = driver.findElement(By.xpath("/html/body/div[2]/div[1]/div/div[1]/div/ul/li[4]/a"));
            actions.moveToElement(element).perform();
            // 使用显式等待
            WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
            // 等待子菜单项出现
            WebElement submenu = wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("/html/body/div[2]/div[1]/div/div[1]/div/ul/li[4]/ul/li[1]")));
            // 点击子菜单项
            submenu.click();

            Thread.sleep(3000 + (long) (Math.random() * 4000));
            // 5. 获取所有窗口句柄
            Set<String> windowHandlesTop = driver.getWindowHandles();
            // 6. 切换到新打开的窗口
            for (String handle : windowHandlesTop) {
                System.out.println("循环窗口信息："+handle+"     title："+driver.getTitle());
                driver.switchTo().window(handle);  // 切换到新窗口
                if ("执业医师_初级职称_中级职称_高级职称_医学精品题库_阿虎医考医学教育网".equals(driver.getTitle())){
                    break;
                }
            }

            driver.findElement(By.xpath("/html/body/div[3]/div[1]/div[1]/a/span")).click();

            // 3. 获取当前窗口的句柄
            String originalWindow = driver.getWindowHandle();
            System.out.println("当前title = "+driver.getTitle());

            Thread.sleep(3000 + (long) (Math.random() * 4000));
            // 4. 等待新窗口打开
            /*WebDriverWait waitNew = new WebDriverWait(driver, Duration.ofSeconds(20));
            waitNew.until(ExpectedConditions.numberOfWindowsToBe(2));  // 等待窗口数为2*/
            // 5. 获取所有窗口句柄
            Set<String> windowHandles = driver.getWindowHandles();
            // 6. 切换到新打开的窗口
            for (String handle : windowHandles) {
                System.out.println("循环窗口信息："+handle+"     title："+driver.getTitle());
                if (!handle.equals(originalWindow)) {
                    driver.switchTo().window(handle);  // 切换到新窗口
                    if ("阿虎医考（编题16年，更懂必考点）".equals(driver.getTitle())){
                        break;
                    }
                }
            }

            System.out.println("当前title = "+driver.getTitle());

            // 获取所有的 cookie 信息
            Set<Cookie> cookies = driver.manage().getCookies();
            Map<String, String> cookieMap = new HashMap<>();
            // 获取每个 cookie 的信息
            for (Cookie cookie : cookies) {
                cookieMap.put(cookie.getName(), cookie.getValue());
            }

            System.out.println("cookieMap = "+JSON.toJSONString(cookieMap));

            // 目标 URL
            //String referer = "https://waph.ahuyk.com";
            // 构造自定义请求头
            Map<String, String> headers = new HashMap<>();
            //headers.put("User-Agent", "Mozilla/5.0 (Linux; Android 10; Mi 9T Pro Build/QKQ1.190910.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/91.0.4472.120 Mobile Safari/537.36 MicroMessenger/8.0.17.2010(0x2800113B) NetType/WIFI Language/zh_CN");
            headers.put("User-Agent", userAgent);
            headers.put("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
            //headers.put("Accept-Encoding", "gzip, deflate, br, zstd");
            headers.put("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8");
            headers.put("Connection", "keep-alive");
            //headers.put("Referer", referer); // 如果需要Referer信息
            headers.put("Upgrade-Insecure-Requests", "1");
            headers.put("Cache-Control", "max-age=0");
            headers.put("content-type", "application/x-www-form-urlencoded; charset=UTF-8");


            // 先更新数据 update t_knowl_cat set isactive = 1  where name like '%中西医结合内科学%' or name like '护理学';
            String querySql = "select id, name, parent_id parentId, href, main_cid mainCid, \"desc\" from t_knowl_cat where isactive = ?";
            List<KnowlCat> data = null;
            try {
                data = PostgreSqlJdbc.queryKnowlCat(List.of(Integer.valueOf(1)),querySql);
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }


            // 需要保存的课题列表
            List<Topic> addTopicList = new ArrayList<>();
            // 课程科目列表
            List<Subject> addSubjectList = new ArrayList<>();
            // 课题和科目关联
            List<TopicSubject> addTopicSubjectList = new ArrayList<>();
            Set<Long> ids = new HashSet<>();
            // 变量需要爬取的分类信息
            for(KnowlCat knowlCat : data){
                System.out.println("分类信息："+JSON.toJSONString(knowlCat));
                Long knowlCatId = knowlCat.getId();

                // Jsoup 模拟请求
                /*String url = "https://waph.ahuyk.com/ahuxueshu/user/SetMainCategory.html";
                headers.put("Referer", "https://waph.ahuyk.com/ahuxueshu/index/GetMainCategoryList.html"); // 如果需要Referer信息
                headers.put("Content-Type", "application/json");
                //mainCid: 110
                // 使用 Jsoup 发送请求，并获取 HTML 页面
                Document document = null;
                //添加参数
                Map<String, String> dataJsoup = new HashMap<>();
                dataJsoup.put("mainCid", knowlCat.getMainCid().toString());
                try {
                    document = Jsoup.connect(url)
                            .headers(headers)  // 设置请求头
                            .cookies(cookieMap)
                            .timeout(10000)     // 设置超时时间
                            //.get();
                            //.data(dataJsoup)
                            .requestBody("{\"mainCid\": "+knowlCat.getMainCid()+"}")
                            .post();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                // 打印抓取到的 HTML 页面
                System.out.println("抓取页面的title信息="+document.title());
                System.out.println(document.body());*/

                // 模拟js请求 获取 单击元素进行js调用(需要选择主分类才能出现子分类）
                //clickEventUploadAly('选择分类-(美国注册护士（RN）)-按钮','206','category','美国注册护士（RN）')
                //*[@id="v-pills-home25"]/div/div[2]/div[1]/p

                //#v-pills-home25 > div > div:nth-child(2) > div:nth-child(1) > p
                String querySqlParent = "select id, name, parent_id parentId, href, main_cid mainCid, \"desc\" from t_knowl_cat where id = ?";
                List<KnowlCat> dataParent = null;
                try {
                    dataParent = PostgreSqlJdbc.queryKnowlCat(List.of(knowlCat.getParentId()),querySqlParent);
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
                KnowlCat knowlCatParent = dataParent.get(0);
                String knowlCatParentIdSelector = knowlCatParent.getHref().replace("#", "");


                // 模拟鼠标移动和点击(选择实体页面的分类下拉)
                //Thread.sleep(30000L);
                Thread.sleep(3000 + (long) (Math.random() * 4000));
                System.out.println(driver.getTitle());
                Actions actions1 = new Actions(driver);

                WebElement element1 = driver.findElement(By.xpath("/html/body/div[3]/div/a/img"));
                actions1.moveToElement(element1).click().perform();

                // 先选主菜单（//*[@id="pills-tab"]/li[3]/a）
                //String mainMenuXpath="//ul[@id=\"pills-tab\"]/li/a[normalize-space(text()) = '"+knowlCatParent.getName()+"']";
                String mainMenuXpath="//ul[@id=\"pills-tab\"]/li/a[@href = '"+knowlCatParent.getHref()+"']";
                driver.findElement(By.xpath(mainMenuXpath)).click();

                //String menuButtonPath="//*[@id=\""+knowlCatParentIdSelector+"\"]/div/div/div[1]/p[@type='onclick' and @data='" + knowlCat.getMainCid() +"']";
                //String menuButtonPath="//div[@id='master']/div[position() mod 2 = 0]/div[1]/p[@onclick and contains(@onclick, 'callFn(') and contains(@onclick, 'type') and @data='453']";
                Thread.sleep(1000 + (long) (Math.random() * 1000));

                //*[@id="v-pills-home0"]/div/div[2]/div[1]/p
                //String menuButtonPath="//div[@id='"+knowlCatParentIdSelector+"']/div/div[position() mod 2 = 0]/div[1]/p[@onclick and contains(@onclick, 'clickEventUploadAly(') and contains(@onclick, '"+knowlCat.getMainCid()+"') and @data='"+knowlCat.getMainCid()+"']";
                String menuButtonPath="//div[@id='"+knowlCatParentIdSelector+"']/div/div/div[1]/p[@data='"+knowlCat.getMainCid()+"']";
                WebElement menuButton = driver.findElement(By.xpath(menuButtonPath));
                menuButton.click();


                // 确定按钮 /html/body/div[3]/div[3]/div[2]/button
                // 调用：onclick="ensure()"
                //使用 WebDriverWait 等待元素
                /*WebDriverWait wait = new WebDriverWait(driver, 10);
                WebElement button = wait.until(ExpectedConditions.elementToBeClickable(By.id("myButton")));
                ((JavascriptExecutor) driver).executeScript("arguments[0].click();", button);*/

                // 将 WebDriver 转换为 JavascriptExecutor
                //JavascriptExecutor jsExecutor = (JavascriptExecutor) driver;
                // 定义要执行的 JavaScript 代码
                //String script = "return getSum(arguments[0], arguments[1]);";
                // 执行 JavaScript 代码并获取返回值
                //Object result = jsExecutor.executeScript(script, 5, 10);

                // 方法 1: 调用页面元素的 click 方法
                //WebElement button = driver.findElement(By.id("myButton"));
                //((JavascriptExecutor) driver).executeScript("arguments[0].click();", button);
                // 方法 2: 直接调用 JavaScript 函数
                //((JavascriptExecutor) driver).executeScript("myFunction();");
                // 方法 3: 调用特定的事件，例如触发一个点击事件
                //((JavascriptExecutor) driver).executeScript("document.getElementById('myButton').click();");

                /*
                elementToBeClickable(By locator)	等待元素变为可点击。
                visibilityOfElementLocated(By locator)	等待元素变为可见。
                presenceOfElementLocated(By locator)	等待元素出现在 DOM 中，但不一定可见。
                visibilityOf(WebElement element)	等待指定的元素可见。
                textToBePresentInElementLocated(By locator, String text)	等待某个元素包含指定的文本。*/
                /*try {
                    WebElement button = wait.until(ExpectedConditions.elementToBeClickable(By.id("myButton")));
                    button.click();
                } catch (TimeoutException e) {
                    System.out.println("Timeout: Element not found or not clickable.");
                }*/

                // 直接调用js
                /*((JavascriptExecutor) driver).executeScript("ensure();");
                Thread.sleep(1000 + (long) (Math.random() * 1000));*/
                Thread.sleep(1000 + (long) (Math.random() * 1000));
                driver.findElement(By.xpath("/html/body/div[3]/div[3]/div[2]/button")).click();
                Thread.sleep(2000 + (long) (Math.random() * 4000));

                //WebElement watibutton = wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("body > div.ahu-section.ahu-tiku-home-section.share-padding-horizontal-sm > div:nth-child(3) > div.tiku_goods_item_right > div.tiku_goods_item_jd > div.tiku_goods_item_jd_top")));
                //watibutton.click();

                // 获取当前分类下的课题信息 ： /html/body/div[4]/div[3] /html/body/div[4]/div[4]
                String pageSource = driver.getPageSource();  // 获取网页源代码
                // 将 HTML 转换为 Jsoup 的 Document 对象
                Document doc = Jsoup.parse(pageSource);
                //System.out.println(doc.html());
                // 使用 Jsoup 进行元素查找和操作
                //System.out.println(doc.title());  // 输出网页标题
                //System.out.println(pageSource);  // 输出网页
                //Elements topicList = doc.select("body > div.ahu-section.ahu-tiku-home-section.share-padding-horizontal-sm > div:nth-child(3)");

                // 使用选择器查找满足条件的元素
                /*Elements matchingDivs = doc.select(
                                "body > div.ahu-section.ahu-tiku-home-section.share-padding-horizontal-sm > div[onclick]"
                        ).stream()
                        *//*.filter(div -> {
                            String onclickValue = div.attr("onclick");
                            // 判断是否完全匹配或部分匹配
                            return onclickValue.equals("ation.href=window.loc'/ahutiku/book/index/tikuType/1/bookId/157.html'")
                                    || onclickValue.contains("window.location.href='/ahutiku/book");
                        })*//*
                        .filter(div -> div.attr("onclick").contains("window.location.href='/ahutiku/book"))
                        .collect(Collectors.toCollection(Elements::new));*/
                // 并且
                //Elements matchingDivs = doc.select("body > div > div[onclick$=.html'][onclick^=window.location.href='/ahutiku/book]");
                // 或者
                //Elements matchingDivs = doc.select("body > div > div[onclick$=.html'],div[onclick^=window.location.href='/ahutiku/book]");
                Thread.sleep(1000);
                // body > div.ahu-section.ahu-tiku-home-section.share-padding-horizontal-sm > div:nth-child(3)
                //Elements matchingDivs = doc.select("body > div.ahu-section.ahu-tiku-home-section.share-padding-horizontal-sm > div[onclick^='window.location.href']");
                //Elements matchingDivs = doc.select("body > div.ahu-section.ahu-tiku-home-section.share-padding-horizontal-sm > div[onclick^='window.location.href']");
                Elements matchingDivs = doc.select("body > div.ahu-section.ahu-tiku-home-section.share-padding-horizontal-sm > div");
                //System.out.println(matchingDivs.toString());  // 输出网页标题
                //Elements matchingDivs = doc.select("body > div.ahu-section.ahu-tiku-home-section.share-padding-horizontal-sm > div[onclick]");

                //Elements matchingDivs = doc.select("body > div.ahu-section.ahu-tiku-home-section.share-padding-horizontal-sm > div");
                //System.out.println(matchingDivs.html());
                //List<WebElement> divsDriver = driver.findElements(By.cssSelector("body > div.ahu-section.ahu-tiku-home-section.share-padding-horizontal-sm > div[onclick$='.html\\''][onclick^='window.location.href=\\'/ahutiku/book']"));
                /*String xxPath = "/html/body/div[4]/div";
                List<WebElement> divsDriver = driver.findElements(By.xpath(xxPath));
                for(WebElement webElementItem : divsDriver){
                    System.out.println("selenium 获取动态属性，譬如动态绑定的事件="+webElementItem.getAttribute("onclick"));
                }*/


                // 输出结果
                for (Element div : matchingDivs) {

                    if(div.toString().contains("onclick=\"window.location.href='/ahutiku/")){
                    //if (true){
                        //System.out.println("课题的全部标签内容："+div.toString());
                        String onclick = div.select("div[onclick]").attr("onclick");
                        String imageSrc = div.select("div[onclick] > div.tiku_goods_item_left > img:nth-child(1)").attr("src");
                        String topicName = div.select("div[onclick] > div.tiku_goods_item_right > div.tiku_goods_item_title").text();
                        System.out.println(topicName+": 输出测试值： "+onclick +" 图片："+ imageSrc);
                        Topic topic = new Topic();
                        // 保存课题
                        SnowflakeIdGenerator generator = new SnowflakeIdGenerator(ThreadLocalRandom.current().nextInt(32), ThreadLocalRandom.current().nextInt(32));
                        long topId = generator.generateId();
                        while (ids.contains(topId)){
                            topId = generator.generateId();
                        }
                        ids.add(topId);
                        topic.setId(topId);
                        topic.setName(topicName);
                        topic.setClickUrl(onclick);
                        topic.setKnowlCatId(knowlCatId);
                        topic.setStatus(1);
                        addTopicList.add(topic);

                        driver.findElement(By.xpath("/html/body/div/div[@onclick and contains(@onclick, \""+onclick+"\")]")).click();
                        Thread.sleep(1000 + (long) (Math.random() * 1000));
                        String currentUrl = driver.getCurrentUrl();
                        //System.out.println("当前地址="+currentUrl);
                        // /html/body/div[4]/a[1] 和 body > div.ahu-chapter-section > a:nth-child(1)  【href="/ahutiku/QuePart/GetPartList.html?partId=9420"  和 onclick="clickEventUploadAly('VIP题库-章节-列表-点击','9420','vip-chapter')"】
                        String pageSourceBySubjectParent = driver.getPageSource();  // 获取科目代码网页源代码
                        Document docBySubjectParent = Jsoup.parse(pageSourceBySubjectParent);
                        Elements docBySubjectParentEs = docBySubjectParent.select("body > div.ahu-chapter-section > a[href^='/ahutiku/QuePart/GetPartList.html?partId=']");
                        //System.out.println(docBySubjectParentEs);
                        for(Element subPes : docBySubjectParentEs){
                            //System.out.println("选择每个元素的内容："+subPes);
                            String hrefSubPes = subPes.attr("href");
                            String onclickSubPes = subPes.attr("onclick");
                            String subPescontents = subPes.select("a > div.share-row > div.share-text-middle > div > p.share-text-truncate1").text();
                            System.out.println(subPescontents + " &&& "+ onclickSubPes + " &&& "+hrefSubPes);
                            Subject subjectParentInfo = new Subject();
                            SnowflakeIdGenerator generatorSubjectParent = new SnowflakeIdGenerator(ThreadLocalRandom.current().nextInt(32), ThreadLocalRandom.current().nextInt(32));
                            long topIdSubjectParent = generatorSubjectParent.generateId();
                            while (ids.contains(topIdSubjectParent)){
                                topIdSubjectParent = generatorSubjectParent.generateId();
                            }
                            ids.add(topIdSubjectParent);
                            subjectParentInfo.setId(topIdSubjectParent);
                            subjectParentInfo.setHref(hrefSubPes);
                            subjectParentInfo.setParentId(0L);
                            subjectParentInfo.setOnclick(onclickSubPes);
                            subjectParentInfo.setStatus(1);
                            subjectParentInfo.setName(subPescontents);
                            addSubjectList.add(subjectParentInfo);

                            // 课题和科目关联
                            TopicSubject topicSubject = new TopicSubject();
                            topicSubject.setSubjectId(topIdSubjectParent);
                            topicSubject.setTopicId(topId);
                            addTopicSubjectList.add(topicSubject);

                            driver.findElement(By.xpath("/html/body/div/a[@onclick and contains(@href, \""+hrefSubPes+"\")]")).click();
                            Thread.sleep(1000 + (long) (Math.random() * 2000));
                            // 子节点 ：/html/body/div[4]/div[1]  和 body > div.ahu-chapter-section > div:nth-child(1)
                            // /html/body/div[4]/div[1]/div   或者  body > div.ahu-chapter-section > div:nth-child(1) > div 获取 part-id 和 onclick
                            // body > div.ahu-chapter-section > div （part-id 和 onclick）
                            String lastNodeInfo = driver.getPageSource();
                            Document lastNodeInfoDoc = Jsoup.parse(lastNodeInfo);
                            Elements lastNodeInfoEts = lastNodeInfoDoc.select("body > div.ahu-chapter-section > div > div[part-id][onclick^=\"jumpUrl('/ahutiku/PrefQue/getQueList/part_id\"]");
                            for(Element lastNodeInfoEt : lastNodeInfoEts){
                                //System.out.println("每个子分类的数据= "+lastNodeInfoEt.toString());

                                String etPartId = lastNodeInfoEt.attr("part-id");
                                String etOnclick = lastNodeInfoEt.attr("onclick");
                                String etText = lastNodeInfoEt.select("div > div > p.share-text-truncate1").text();
                                System.out.println("etText = "+etText);
                                Subject subjectInfo = new Subject();
                                SnowflakeIdGenerator generatorSubject = new SnowflakeIdGenerator(ThreadLocalRandom.current().nextInt(32), ThreadLocalRandom.current().nextInt(32));
                                long topIdSubject = generatorSubject.generateId();
                                while (ids.contains(topIdSubject)){
                                    topIdSubject = generatorSubject.generateId();
                                }
                                ids.add(topIdSubject);
                                subjectInfo.setId(topIdSubject);
                                subjectInfo.setParentId(topIdSubjectParent);
                                subjectInfo.setName(etText);
                                subjectInfo.setPartId(Long.valueOf(etPartId));
                                subjectInfo.setOnclick(etOnclick);
                                subjectInfo.setStatus(1);
                                addSubjectList.add(subjectInfo);

                            }

                            System.out.println("最后一层的科目信息："+ driver.getTitle());
                            driver.navigate().back();
                            System.out.println("当前地址="+driver.getCurrentUrl());
                        }

                        System.out.println("需要回到上级菜单");
                        driver.navigate().back();
                        System.out.println("当前地址="+driver.getCurrentUrl());
                    }
                }
                // 回退到上一页
                //driver.navigate().back();
                // 访问页面2
                //driver.get("https://waph.ahuyk.com/ahutiku/Exercise/index.html");
                Thread.sleep(1000 + (long) (Math.random() * 2000));

            }

            // 保存数据
            if(addTopicList.size()> 0 && addSubjectList.size() > 0 && addTopicSubjectList.size() > 0){
                String topicSql = "INSERT INTO t_topic (id,name,knowl_cat_id,click_url,status) "
                        + "VALUES (?, ?, ?, ?, ?);";

                String subjectSql = "INSERT INTO t_suject (id,name,parent_id,href,onclick,part_id,status) "
                        + "VALUES (?, ?, ?, ?, ?, ?, ?);";

                String topicSubjectSql = "INSERT INTO t_topic_suject (topic_id, suject_id) "
                        + "VALUES (?, ?);";

                try {
                    int topicSqlCount = PostgreSqlJdbc.batchInsertTopic(addTopicList, topicSql, 100);
                    System.out.println("topicSqlCount = "+topicSqlCount);

                    int subjectSqlCount = PostgreSqlJdbc.batchInsertSubject(addSubjectList, subjectSql, 100);
                    System.out.println("subjectSqlCount = "+subjectSqlCount);

                    int topicSubjectSqlCount = PostgreSqlJdbc.batchInsertTopicSubject(addTopicSubjectList, topicSubjectSql, 100);
                    System.out.println("topicSubjectSqlCount = "+topicSubjectSqlCount);


                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }else{
                System.out.println("数据不全,不能保存");
            }
            System.out.println("结束时间："+LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            System.out.println("结束时间："+LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            Set<String> windowHandles = driver.getWindowHandles();
            // 6. 切换到新打开的窗口
            for (String handle : windowHandles) {
                driver.switchTo().window(handle);
                driver.close();
            }
            driver.quit();
        }
    }

    // 等待页面加载完成的自定义方法
    private static void waitForPageLoad(WebDriver driver) {
        JavascriptExecutor js = (JavascriptExecutor) driver;
        // 等待页面加载完成（直到没有任何正在加载的资源）
        js.executeScript("return document.readyState").equals("complete");
    }
}
